To main site
Back for more posts
technical
self-documenting
AWS
Share:
5 min read - 895 words
Date published: 10-Oct-2022
Date modified: 10-Oct-2022

Creating an "Over-engineer"-ed personal blog

This is one project I am particularly proud of, as part of my overall website (which I have shown my overall architecture before). You can check it our live as blogs.datbdo.com or https://datbdo.com/blogs . In this post though, I just want to run through my history of building (as well as what I want to do next)

1. Data modelling to infrastructure

Motivation

I know from the start that my website will need a blogging feature so I can improve my ngữ văn skill.

Requirements

  • Markdown-based content with some arbitrary associated metadata
  • Role based access control (author can edit/publish/etc, others can only view)
  • On the fly editor, can paste image and usable on mobile

Implementation

AWS Amplify + React simplify a lot of the infrastructure here. I used GraphQL schema (attached) to define the Post object looks like and Amplify handle the rest (IAM Cognito roles, DynamoDB and API endpoints). Final piece is to slap a front end markdown editor, markdown renderer and some logic to CRUD

image.png

image.png

image.png

2. Introduce and integrate variants

Motivation

While the editor was nice, it was not too mobile friendly, which is what I have with me majority of the time I want to write blog (offline on the subway, before going to bed, etc)

Furthermore, I wanted to accept smaller form of content such as random thoughts and maybe an image or two.

Requirements

  • A way to accept multiple data sources into blog pages
  • Display content accordingly based on source and length

Implementation

I did not want to handle any data migration so I make sure to keep my data model and work backwards from there. Luckily, past me was quite big brain to make data attributes a JSON. This means for my site blog data, I can just dump markdown text string. For others with different attributes, I just have to dump all the necessary info in enough for the front end to know what to render.

After locking down the data model and display strategy, the next step was to ingest data sources. I quickly realized short content can be populated with tweets and Instagram posts while Notion can be a pretty good blog post too since it has a great editor. With these data sources in mind, I come up with an ingress - transform - egress & notification model (see attached)

image.png

This seems to be quite extensible. It can support both pull (cron lambda) and push (webhook, IFTTT) type of data sources. On the other end, because of the transformer, the store/egress does not even need to care where the data is from (only the front end do for rendering). Plus, I was able to have a different lambda to consume the egress to make a CRUD notification system within my website.

image.png

3. From runtime heavy to build time heavy

Motivation

On a random day I tried to search my stuff on Google and to my surprise, nothing show up, no matter what keywords/terms I put in. Took me almost no time to realize since my blog was part of Single Page Web App (SPA), it crippled my search engine optimization (subsequently load time as well)

Requirements

  • Make the page load faster and content more searchable over the internet

Implementation

The best way to easily do this is to pre-generate all visual aspect for the blog’s front end content, making them static, instead of calculating and requesting content per site visitor’s request. I opted in to use GatsbyJS, a static site generator that allow you to bring your own content management. Luckily, my content is all stored nicely formatted in a DynamoDB, which can be easily accessed with right role and provided plugin.

The next challenge is the blog site will now be build and re-deploy on new content generated (vs my main website which is only deploy on code push). I decided to refactor the blog separately into its own sub-project then deploy it via Vercel.app. With Vercel’s build cache and deploy trigger webhook, I can control when to re-generate the content and keep the deployment process for blog fast (<15 seconds between publish content vs it being visible)

image.png

Technically my main website and my blog now separated into 2 sites. However, with the magic of Iframe, with some 2 way binding to sync routes, I managed to make the blog behave naturally within my main site as well.

4. TODO: Notify to the world

Motivation

I don't have a way to tell people who has visited I posted something new

Current thought process

Technically I can just consume from egress then hook it up to SES or something but I want to manage the subscriber’s list the right way 🤔. Maybe MailChimp or ConvertKit could do the trick

5. TODO: Enable comments

Motivation

I do like feedback and a way to see if my contents are well received

Current thought process

My current data model already included comments capabilities. Front end isn't a problem neither. The challenge is to filter out in a automatic/semi-automatic way toxic issue. Also who would be allowed to comment, under what identity 🤔

===

That's pretty much it. Is it overkill? Maybe but it feels good to have a consolidated pages for people to guess what kind of person I am 😅